diff options
Diffstat (limited to 'app/[lng]')
| -rw-r--r-- | app/[lng]/partners/(partners)/swp-document-upload/vendor-document-page.tsx | 92 |
1 files changed, 80 insertions, 12 deletions
diff --git a/app/[lng]/partners/(partners)/swp-document-upload/vendor-document-page.tsx b/app/[lng]/partners/(partners)/swp-document-upload/vendor-document-page.tsx index dc6fbe7c..67fbfd9f 100644 --- a/app/[lng]/partners/(partners)/swp-document-upload/vendor-document-page.tsx +++ b/app/[lng]/partners/(partners)/swp-document-upload/vendor-document-page.tsx @@ -5,16 +5,20 @@ import { useDropzone } from "react-dropzone"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { Alert, AlertDescription } from "@/components/ui/alert"; import { Skeleton } from "@/components/ui/skeleton"; +import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { InfoIcon, Upload } from "lucide-react"; import { SwpTable } from "@/lib/swp/table/swp-table"; +import { SwpInboxTable } from "@/lib/swp/table/swp-inbox-table"; import { SwpTableToolbar } from "@/lib/swp/table/swp-table-toolbar"; import { fetchVendorDocuments, fetchVendorProjects, fetchVendorSwpStats, getVendorSessionInfo, + fetchVendorUploadedFiles, } from "@/lib/swp/vendor-actions"; import type { DocumentListItem } from "@/lib/swp/document-service"; +import type { SwpFileApiResponse } from "@/lib/swp/api-client"; import { toast } from "sonner"; interface VendorDocumentPageProps { @@ -27,6 +31,7 @@ export default function VendorDocumentPage({ searchParams }: VendorDocumentPageP // 상태 관리 const [documents, setDocuments] = useState<DocumentListItem[]>([]); + const [inboxFiles, setInboxFiles] = useState<SwpFileApiResponse[]>([]); const [projNo, setProjNo] = useState(initialProjNo); const [projects, setProjects] = useState<Array<{ PROJ_NO: string; PROJ_NM: string }>>([]); const [stats, setStats] = useState({ @@ -46,12 +51,16 @@ export default function VendorDocumentPage({ searchParams }: VendorDocumentPageP const [isRefreshing, setIsRefreshing] = useState(false); const [error, setError] = useState<string | null>(null); + // 탭 상태 + const [activeTab, setActiveTab] = useState("inbox"); + // 클라이언트 필터 const [searchFilters, setSearchFilters] = useState({ docNo: (searchParams.docNo as string) || "", docTitle: (searchParams.docTitle as string) || "", pkgNo: (searchParams.pkgNo as string) || "", stage: (searchParams.stage as string) || "", + status: (searchParams.status as string) || "", }); // Dropzone 설정 @@ -86,12 +95,14 @@ export default function VendorDocumentPage({ searchParams }: VendorDocumentPageP // 초기 프로젝트가 있으면 문서 로드 if (initialProjNo) { - const [documentsData, statsData] = await Promise.all([ + const [documentsData, statsData, inboxFilesData] = await Promise.all([ fetchVendorDocuments(initialProjNo), fetchVendorSwpStats(initialProjNo), + fetchVendorUploadedFiles(initialProjNo), ]); setDocuments(documentsData); setStats(statsData); + setInboxFiles(inboxFilesData); } } catch (err) { console.error("초기 데이터 로드 실패:", err); @@ -109,13 +120,15 @@ export default function VendorDocumentPage({ searchParams }: VendorDocumentPageP setIsRefreshing(true); setError(null); - const [documentsData, statsData] = await Promise.all([ + const [documentsData, statsData, inboxFilesData] = await Promise.all([ fetchVendorDocuments(projNo), fetchVendorSwpStats(projNo), + fetchVendorUploadedFiles(projNo), ]); setDocuments(documentsData); setStats(statsData); + setInboxFiles(inboxFilesData); toast.success("문서 목록을 갱신했습니다"); } catch (err) { console.error("문서 로드 실패:", err); @@ -150,7 +163,7 @@ export default function VendorDocumentPage({ searchParams }: VendorDocumentPageP loadDocuments(); }; - // 클라이언트 사이드 필터링 + // 클라이언트 사이드 필터링 - VDR Documents const filteredDocuments = useMemo(() => { return documents.filter((doc) => { if (searchFilters.docNo && !doc.DOC_NO.toLowerCase().includes(searchFilters.docNo.toLowerCase())) { @@ -165,10 +178,43 @@ export default function VendorDocumentPage({ searchParams }: VendorDocumentPageP if (searchFilters.stage && doc.STAGE !== searchFilters.stage) { return false; } + if (searchFilters.status) { + const statusLower = searchFilters.status.toLowerCase(); + const docStatus = doc.LTST_ACTV_STAT?.toLowerCase() || ""; + if (!docStatus.includes(statusLower)) { + return false; + } + } return true; }); }, [documents, searchFilters]); + // 클라이언트 사이드 필터링 - Inbox Files + const filteredInboxFiles = useMemo(() => { + return inboxFiles.filter((file) => { + if (searchFilters.docNo && !file.OWN_DOC_NO.toLowerCase().includes(searchFilters.docNo.toLowerCase())) { + return false; + } + if (searchFilters.docTitle && !file.FILE_NM.toLowerCase().includes(searchFilters.docTitle.toLowerCase())) { + return false; + } + if (searchFilters.pkgNo && !file.PKG_NO?.toLowerCase().includes(searchFilters.pkgNo.toLowerCase())) { + return false; + } + if (searchFilters.stage && file.STAGE !== searchFilters.stage) { + return false; + } + if (searchFilters.status) { + const statusLower = searchFilters.status.toLowerCase(); + const fileStatus = file.STAT_NM?.toLowerCase() || file.STAT?.toLowerCase() || ""; + if (!fileStatus.includes(statusLower)) { + return false; + } + } + return true; + }); + }, [inboxFiles, searchFilters]); + if (isLoading) { return ( <Card> @@ -212,7 +258,7 @@ export default function VendorDocumentPage({ searchParams }: VendorDocumentPageP )} {/* 통계 카드 */} - <div className="grid grid-cols-1 md:grid-cols-4 gap-4"> + {/* <div className="grid grid-cols-1 md:grid-cols-4 gap-4"> <Card> <CardHeader className="pb-3"> <CardDescription>할당된 문서</CardDescription> @@ -239,7 +285,7 @@ export default function VendorDocumentPage({ searchParams }: VendorDocumentPageP </CardTitle> </CardHeader> </Card> - </div> + </div> */} {/* 안내 메시지 */} {documents.length === 0 && !projNo && ( @@ -251,7 +297,7 @@ export default function VendorDocumentPage({ searchParams }: VendorDocumentPageP </Alert> )} - {/* 메인 테이블 */} + {/* 메인 테이블 - 탭 구조 */} <Card> <CardHeader> <SwpTableToolbar @@ -270,12 +316,34 @@ export default function VendorDocumentPage({ searchParams }: VendorDocumentPageP /> </CardHeader> <CardContent> - <SwpTable - documents={filteredDocuments} - projNo={projNo} - vendorCode={vendorInfo?.vendorCode || ""} - userId={String(vendorInfo?.vendorId || "")} - /> + <Tabs value={activeTab} onValueChange={setActiveTab} className="w-full"> + <TabsList className="grid w-full grid-cols-2"> + <TabsTrigger value="inbox"> + SBOX (ALL) + {/* ({filteredInboxFiles.length}) */} + </TabsTrigger> + <TabsTrigger value="documents"> + VDR Documents (Received) + {/* ({filteredDocuments.length}) */} + </TabsTrigger> + </TabsList> + <TabsContent value="inbox" className="mt-4"> + <SwpInboxTable + files={filteredInboxFiles} + projNo={projNo} + vendorCode={vendorInfo?.vendorCode || ""} + userId={String(vendorInfo?.vendorId || "")} + /> + </TabsContent> + <TabsContent value="documents" className="mt-4"> + <SwpTable + documents={filteredDocuments} + projNo={projNo} + vendorCode={vendorInfo?.vendorCode || ""} + userId={String(vendorInfo?.vendorId || "")} + /> + </TabsContent> + </Tabs> </CardContent> </Card> </div> |
